/**
 * 认证服务
 */

const Logger = require('../utils/logger')
const Validator = require('../utils/validator')
const Generator = require('../utils/generator')
const config = require('../config/config')

class AuthService {
  constructor(userRepo, tokenRepo, inviteRepo, userService, inviteService, smsService) {
    this.userRepo = userRepo
    this.tokenRepo = tokenRepo
    this.userService = userService
    this.inviteService = inviteService
    this.smsService = smsService
  }

  /**
   * 密码登录
   */
  async passwordLogin(account, password, openid) {
    Logger.info('AuthService', '密码登录', { account })

    if (!account || !password) {
      throw new Error('账号和密码不能为空')
    }

    // 查询用户
    const user = await this.userRepo.findByAccount(account)
    if (!user) {
      throw new Error('用户不存在')
    }

    // 验证密码（明文比对）
    if (user.password !== password) {
      throw new Error('密码错误')
    }

    // 检查用户状态
    if (user.status === 'disabled') {
      throw new Error('账号已被禁用')
    }

    // 生成token
    const token = Generator.generateToken(user._id)

    // 保存token
    await this.tokenRepo.saveToken({
      userId: user._id,
      token: token,
      createTime: new Date(),
      expireTime: new Date(Date.now() + config.token.expireTime),
      openid: openid
    })

    // 更新登录信息
    await this.userService.updateLoginInfo(user._id, openid)

    // 格式化用户信息
    const userInfo = this.userService.formatUserInfo(user)

    Logger.info('AuthService', '密码登录成功', { userId: user._id })

    return { token, userInfo }
  }

  /**
   * 验证码快速登录（支持自动注册，新用户需要邀请码）
   */
  async quickLogin(phone, verifyCode, inviteCode, openid) {
    Logger.info('AuthService', '快速登录', { phone, hasInviteCode: !!inviteCode })

    if (!phone || !verifyCode) {
      throw new Error('手机号和验证码不能为空')
    }

    // 验证手机号格式
    Validator.validatePhone(phone)

    // 验证验证码
    await this.smsService.verifyCode(phone, verifyCode, 'login')

    // 查询用户
    let user = await this.userRepo.findByPhone(phone)
    let isNewUser = false
    let rewardPoints = 0

    if (!user) {
      // 新用户，需要邀请码才能注册
      if (!inviteCode) {
        throw new Error('新用户注册需要邀请码')
      }

      // 验证邀请码
      Logger.info('AuthService', '新用户注册，验证邀请码', { inviteCode })
      await this.inviteService.validateInviteCode(inviteCode)

      // 自动注册新用户
      const defaultPassword = 'pwd' + phone.slice(-6)  // 格式：pwd138000
      const userData = {
        username: phone,
        phone: phone,
        password: defaultPassword,
        nickname: `用户${phone.slice(-4)}`,
        avatar: Generator.randomAvatar(),
        openid: openid,
        hasDefaultPassword: false
      }

      const result = await this.userService.createUser(userData)
      user = result.userInfo
      isNewUser = true

      // 使用邀请码（记录邀请关系并发放积分）
      rewardPoints = await this.inviteService.useInviteCode(inviteCode, user._id, phone)

      Logger.info('AuthService', '新用户自动注册成功', { userId: user._id, rewardPoints })
    } else {
      // 老用户，直接登录
      // 检查用户状态
      if (user.status === 'disabled') {
        throw new Error('账号已被禁用')
      }

      // 更新登录信息
      await this.userService.updateLoginInfo(user._id, openid)
      Logger.info('AuthService', '老用户登录', { userId: user._id })
    }

    // 生成token
    const token = Generator.generateToken(user._id)

    // 保存token
    await this.tokenRepo.saveToken({
      userId: user._id,
      token: token,
      createTime: new Date(),
      expireTime: new Date(Date.now() + config.token.expireTime),
      openid: openid
    })

    // 格式化用户信息
    const userInfo = this.userService.formatUserInfo(user)
    
    // 如果是新用户，更新积分信息
    if (isNewUser && rewardPoints > 0) {
      userInfo.points = config.user.defaultPoints + rewardPoints
    }

    Logger.info('AuthService', '快速登录成功', { userId: user._id, isNewUser, rewardPoints })

    return { 
      token, 
      userInfo, 
      message: isNewUser ? `注册成功！获得${config.user.defaultPoints + rewardPoints}积分` : '登录成功',
      isNewUser,
      rewardPoints
    }
  }

  /**
   * 用户注册
   */
  async register(registerData, openid) {
    Logger.info('AuthService', '用户注册', { username: registerData.username, phone: registerData.phone })

    const { username, password, confirmPassword, phone, email, verifyCode, inviteCode } = registerData

    // 参数验证
    if (!username || !password || !confirmPassword || !phone || !inviteCode) {
      throw new Error('请填写完整信息')
    }

    // 密码一致性验证
    if (password !== confirmPassword) {
      throw new Error('两次输入的密码不一致')
    }

    // 验证验证码
    await this.smsService.verifyCode(phone, verifyCode, 'register')

    // 验证邀请码
    const inviteCodeInfo = await this.inviteService.validateInviteCode(inviteCode)

    // 创建用户
    const userData = {
      username,
      password,
      phone,
      email: email || '',
      nickname: username,
      openid: openid,
      hasDefaultPassword: false
    }

    const { userId, userInfo } = await this.userService.createUser(userData)

    // 使用邀请码（记录邀请关系并发放积分）
    const rewardPoints = await this.inviteService.useInviteCode(inviteCode, userId, phone)

    // 生成token
    const token = Generator.generateToken(userId)

    // 保存token
    await this.tokenRepo.saveToken({
      userId: userId,
      token: token,
      createTime: new Date(),
      expireTime: new Date(Date.now() + config.token.expireTime),
      openid: openid
    })

    // 更新用户信息中的积分
    userInfo.points = config.user.defaultPoints + rewardPoints

    Logger.info('AuthService', '注册成功', { userId, rewardPoints })

    return { token, userInfo: this.userService.formatUserInfo(userInfo) }
  }

  /**
   * 微信授权登录
   */
  async wechatLogin(openid) {
    Logger.info('AuthService', '微信授权登录', { openid })

    if (!openid) {
      throw new Error('微信授权失败')
    }

    // 查询用户
    const user = await this.userRepo.findByOpenid(openid)
    if (!user) {
      // 用户未注册，需要引导注册
      return {
        needRegister: true,
        message: '请完成注册'
      }
    }

    // 检查用户状态
    if (user.status === 'disabled') {
      throw new Error('账号已被禁用')
    }

    // 生成token
    const token = Generator.generateToken(user._id)

    // 保存token
    await this.tokenRepo.saveToken({
      userId: user._id,
      token: token,
      createTime: new Date(),
      expireTime: new Date(Date.now() + config.token.expireTime),
      openid: openid
    })

    // 更新登录信息
    await this.userService.updateLoginInfo(user._id, openid)

    // 格式化用户信息
    const userInfo = this.userService.formatUserInfo(user)

    Logger.info('AuthService', '微信登录成功', { userId: user._id })

    return { token, userInfo, needRegister: false }
  }

  /**
   * 微信授权注册
   */
  async wechatRegister(wechatInfo, phone, verifyCode, inviteCode, openid) {
    Logger.info('AuthService', '微信授权注册', { phone, openid })

    if (!phone || !verifyCode || !inviteCode) {
      throw new Error('请填写完整信息')
    }

    // 验证手机号
    Validator.validatePhone(phone)

    // 验证验证码
    await this.smsService.verifyCode(phone, verifyCode, 'register')

    // 验证邀请码
    const inviteCodeInfo = await this.inviteService.validateInviteCode(inviteCode)

    // 创建用户
    const userData = {
      username: phone,
      password: 'pwd' + phone.slice(-6), // 默认密码，格式：pwd138000
      phone: phone,
      nickname: wechatInfo.nickName || `用户${phone.slice(-4)}`,
      avatar: wechatInfo.avatarUrl || Generator.randomAvatar(),
      openid: openid,
      hasDefaultPassword: false
    }

    const { userId, userInfo } = await this.userService.createUser(userData)

    // 使用邀请码
    const rewardPoints = await this.inviteService.useInviteCode(inviteCode, userId, phone)

    // 生成token
    const token = Generator.generateToken(userId)

    // 保存token
    await this.tokenRepo.saveToken({
      userId: userId,
      token: token,
      createTime: new Date(),
      expireTime: new Date(Date.now() + config.token.expireTime),
      openid: openid
    })

    // 更新用户信息中的积分
    userInfo.points = config.user.defaultPoints + rewardPoints

    Logger.info('AuthService', '微信注册成功', { userId, rewardPoints })

    return { token, userInfo: this.userService.formatUserInfo(userInfo) }
  }
}

module.exports = AuthService

